#include <iostream>
#include <vector>

#include <Python.h>
#include <google/tcmalloc.h>
#include <gperftools/malloc_hook.h>
#include <gperftools/malloc_extension.h>

#include <windows.h>

// C++对象模型里边的菱形结构

// hook 屏幕输入输出
//class PyConsole

/**
 * @brief: 执行脚本
 * 
 */
int eval(const char* script)
{
    PyObject *m, *d, *v;
    m = PyImport_AddModule("__main__");
    if(NULL == m)
    {
        std::cout << "add module faild !" << std::endl;
        return -1;
    }
    d = PyModule_GetDict(m);
    // param1: 需要执行的语句
    // param2: 表示这段代码从哪来的？ 文件 输入 eval。不同的输入可能有一些特殊处理，比如文件会读取注释设置编码？对tab和space混合的校验不一样？
    // param3: 全局对象环境
    // param4: 局部对象环境
    v = PyRun_String(script, Py_single_input, d, d);
    //需要safe版本
    //Py_DECREF(v);

// /// 输出当前脚本产生的错误信息	
// #define SCRIPT_ERROR_CHECK()																\
// {																							\
//  	if (PyErr_Occurred())																	\
//  	{																						\
// 		PyErr_PrintEx(0);																	\
// 	}																						\
// }
    // 直接直接一段字符串
    //PyRun_SimpleString(script);
    return 0;
}

int n_g = 0;

void _hook_new(const void* ptr, size_t size)
{
    //tc_malloc(sizeof(int));
    n_g += 1;
}

void test_tcmalloc()
{
    MallocHook hook;
    hook.AddNewHook(_hook_new);
    char* data_ptr = new char[1024];
    delete []data_ptr;
    hook.RemoveNewHook(_hook_new);
}

void test_python()
{
    Py_Initialize();
    std::cout << "start:" << std::endl;
    //Py_SetPythonHome(NULL);
    eval("import ptvsd");
    eval("import sys");
    eval("print(sys.path)");
    std::cout << "end:" << std::endl;

    //tc_malloc_stats();

    Py_Finalize();
}

// 脚本变量类型
enum ScriptValueType {
    kString = 0,  // 标准c字符串（\0结尾）
    kBytes  = 1,  // 
    kInt = 2,     // 
    KNumber = 1,  // 自适应int-float
};

class EmptyClass
{

};
void sizeof_empty_class()
{
    EmptyClass obj;
    std::cout << "empty class size: " << sizeof(obj) << std::endl;
}

void unorder_map_has_no_order()
{

}

void vector_append()
{
    std::vector<int> vec;
    // 有右值参数版本
}

int main()
{
    sizeof_empty_class();

    //HeapLeakChecker heap_checker("s");
    test_python();
    
    //int64_t bytes = heap_checker.BytesLeaked();
    //int64_t obj_cnt = heap_checker.ObjectsLeaked();
    //HeapProfilerStart("heap_profiler.txt");
    tc_malloc_stats();



    //tc_malloc_stats();

    //MallocExtension::instance()->VerifyAllMemory();

    // while(true)
    // {
    //     test_tcmalloc();
    // }

    HANDLE h = CreateFileA("111", GENERIC_WRITE, 0, NULL,
                         CREATE_ALWAYS, 0, NULL);
    //HeapProfilerDump("d");
    //HeapProfilerStop();

    return 0;
}

